/* (PARI-GP) R. J. Cano, From Nov 2015 to May 2016

  Purpose:

     Experimental script gathering several routines useful when working with the digits of integer numbers and their permutations viewed as the components for vectors. Base independent implementations for defining, analyzing and experiencing with A215940, A217626, A211869, and A237265, among other related sequences;

  Modifications:
  
    (On: May 14 2016. By: author) Summary: Insertion of additional code for working with the Steinhaus-Jhonson-Algorithm, and minor editing in comments taking into account recent interpretations.

Hint: If you are about to compile this file with GP2C please remember to apply the "-g" option. For more details please refer to your copy of GP2C documentation.

*/

/* This comment could be repeated "as is" later if necessary.

      "Uniformly complementary set" (definition): It is an "U. c. set" any partially ordered set "S" containing k integers such that, given an integer constant R, those elements in S placed at symmetric positions are mutually one the arithmetic complement to R of the other, this is: x[i]+x[k-i+1]=R, for every i in 1<=i<=k and x[i], x[k-i+1] in S;

*/

/* 
  For the human reader, intended to return the glance of an stub from a large vector in the form of another vector.
*/
vecZoom(Input,howMany,InitialOffset=1)={
  my(q=#Input);
  my(z=min(q,howMany));
  my(s=InitialOffset-1);
  if(z==q,return(Input));
  if(s+z>q,return([]));
  vector(z,i,Input[s+i])
}

PermutationsAlgorithm(n,k)=numtoperm(n,k); /* No longer used in such way, also all the code calling this one! */

/* Miscellaneous routines */

vecDiff1(v)=vector(#v-1,i,v[i+1]-v[i]);

vecDiff(v,k=1)={my(w=vector(#v-k,j,((-1)^(k%2))*sum(i=0,k,((-1)^(i%2))*binomial(k,i)*v[j+i])));w}

vecVecsum(w)=vector(#w,i,vecsum(w[i]));

vecFirstPartialSums(v)=vector(#v-1,j,sum(i=1,j,v[i]));

vecFirstPartialSums2(v)=vector(#v,j,vecFirstPartialSums(v[j]));

vecRemoveLeadingZeros(v)={my(Q,a);if(v==vector(#v,j,0),a=[0],Q=1;while(!v[Q],Q++);a=vector(#v-Q+1,z,v[-1+z+Q]));a}

vecRemoveLeadingZeros2(w)=vector(#w,j,vecRemoveLeadingZeros(w[j]));

vecRemoveTrailingZeros(v)={my(Q,a);if(v==vector(#v,j,0),a=[0],Q=#v;while(!v[Q],Q--);a=vector(Q,z,v[z]));a}

vecRemoveTrailingZeros2(w)=vector(#w,j,vecRemoveTrailingZeros2(w[j]));

vecRemoveZeroEdges(v)=vecRemoveLeadingZeros(vecRemoveTrailingZeros(v));

vecRemoveZeroEdges2(w)=vector(#w,j,vecRemoveZeroEdges(w[j]));

vecRemoveMiddleX(v,X)={
  my(l:list,i=2,j);
  l=List();
  if(#v==1,return(v));
  listput(l,v[1]);
  while(1,
    while((v[i]!=X)&&(i<#v),
      listput(l,v[i]);
      i++
    );
    if(i<#v,
      j=i;
      while((v[j]==X)&&(j<#v),
        j++
      );
      if(j<#v,
        listput(l,v[j]);
        i=j+1
      ,
        listput(l,v[#v]);
        return(vector(#l,i,l[i]))
      );
    ,
      listput(l,v[#v]);
      return(vector(#l,i,l[i]))
    )
  )
}

vecRemoveMiddleX2(w,X)=vector(#w,i,vecRemoveMiddleX(w[i],X));

vecGCD(V)={my(a=V[1][1]);for(i=1,#V,for(j=1,#(V[i]),a=gcd(a,V[i][j]);if(a==1,return(1))));a}

isSymmetric(v)={my(q=(#v-((#v)%2))/2);for(k=1,q,if(v[k]!=v[#v-k+1],return(0)));1}

Symmetry(v)=if(isSymmetric(abs(v)),if(isSymmetric(v),1,-1),0);

contained(v1,v2)={ /* Upgrade */
  my(q,c=#v2-#v1,t);
  if(c>=0,
    for(k=0,c,
      t=0;
      for(j=1,#v1,
        if(v1[j]!=v2[k+j],
          t=1;
          break
        )
      );
      if(!t,
        q++
      )
    )
  );
  q
}

vecSubtractAligningToRight(v2,v1,fmt=0)={my(vv=max(#v2,#v1),w2,w1,w0,s);w2=vector(vv,j,0);w1=vector(vv,j,0);s=vv-#v2;for(u=1,#v2,w2[s+u]=v2[u]);s=vv-#v1;for(u=1,#v1,w1[s+u]=v1[u]);w0=w2-w1;if(fmt,vecRemoveLeadingZeros(w0),w0)}

vecAddAligningToRight(v2,v1,fmt=0)={my(vv=max(#v2,#v1),w2,w1,w0,s);w2=vector(vv,j,0);w1=vector(vv,j,0);s=vv-#v2;for(u=1,#v2,w2[s+u]=v2[u]);s=vv-#v1;for(u=1,#v1,w1[s+u]=v1[u]);w0=w2+w1;if(fmt,vecRemoveLeadingZeros(w0),w0)}

vecsumAligningToRight(v,fmt=0)={my(a=[0]);for(k=1,#v,a=vecAddAligningToRight(a,v[k]));if(fmt,vecRemoveLeadingZeros(a),a)}

vecAntiSymmetric(p0)={
  my(p=vector(2));
  p[1]=vector(#p0,i,p0[i]-p0[#p0-i+1]);
  p[2]=vector(#p[1],j,(p[1][j]+p[1][#p[1]])/2);
  p
}

vecPermute(v0,maxItems)={ /* Permutations for generic "letters". Output in increasing sequence. */
  my(Q=(!!maxItems)*min(maxItems,(#v0)!)+(!maxItems)*((#v0)!));
  my(v=vector(Q,i,numtoperm(#v0,i-1)));
  forvec(y=[[1,Q],[1,#v0]],v[y[1]][y[2]]=v0[v[y[1]][y[2]]]);
  v
}

/* The uniformly complementary 1st half of uniformly complementary permutations of permutations for n=3; None of the following elements nor their corresponding complementary can be generated as the output of standard SJT algorithm and this fact is interesting due its implication for autosimilarity since output for SJT algorithm doesn't behave the same kind of autosimilarity of the first differences observed for the output of Narayana Pandita Or Schmuel Zaks algorithms. Here the alternative in order to observe a symmetric distribution pattern of complementary elements is to re-implement the SJT in a way such that the diagonals are fixed, always of the same kind. Always "/" or always "\" (There are (n-1)! of those "diagonals"). 
 
[
[[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]], 
[[0, 1, 2], [0, 2, 1], [1, 2, 0], [1, 0, 2], [2, 0, 1], [2, 1, 0]], 
[[0, 1, 2], [1, 0, 2], [0, 2, 1], [2, 0, 1], [1, 2, 0], [2, 1, 0]], 
[[0, 1, 2], [1, 0, 2], [2, 0, 1], [0, 2, 1], [1, 2, 0], [2, 1, 0]], 
[[0, 1, 2], [1, 2, 0], [0, 2, 1], [2, 0, 1], [1, 0, 2], [2, 1, 0]], 
[[0, 1, 2], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], [2, 1, 0]], 
[[0, 1, 2], [2, 0, 1], [1, 0, 2], [1, 2, 0], [0, 2, 1], [2, 1, 0]], 
[[0, 1, 2], [2, 0, 1], [1, 2, 0], [1, 0, 2], [0, 2, 1], [2, 1, 0]], 

[[0, 2, 1], [0, 1, 2], [1, 0, 2], [1, 2, 0], [2, 1, 0], [2, 0, 1]], 
[[0, 2, 1], [0, 1, 2], [1, 2, 0], [1, 0, 2], [2, 1, 0], [2, 0, 1]],
[[0, 2, 1], [1, 0, 2], [0, 1, 2], [2, 1, 0], [1, 2, 0], [2, 0, 1]],
[[0, 2, 1], [1, 0, 2], [2, 1, 0], [0, 1, 2], [1, 2, 0], [2, 0, 1]],
[[0, 2, 1], [1, 2, 0], [0, 1, 2], [2, 1, 0], [1, 0, 2], [2, 0, 1]],
[[0, 2, 1], [1, 2, 0], [2, 1, 0], [0, 1, 2], [1, 0, 2], [2, 0, 1]], 
[[0, 2, 1], [2, 1, 0], [1, 0, 2], [1, 2, 0], [0, 1, 2], [2, 0, 1]], 
[[0, 2, 1], [2, 1, 0], [1, 2, 0], [1, 0, 2], [0, 1, 2], [2, 0, 1]], 

[[1, 0, 2], [0, 1, 2], [0, 2, 1], [2, 0, 1], [2, 1, 0], [1, 2, 0]], 
[[1, 0, 2], [0, 1, 2], [2, 0, 1], [0, 2, 1], [2, 1, 0], [1, 2, 0]], 
[[1, 0, 2], [0, 2, 1], [0, 1, 2], [2, 1, 0], [2, 0, 1], [1, 2, 0]], 
[[1, 0, 2], [0, 2, 1], [2, 1, 0], [0, 1, 2], [2, 0, 1], [1, 2, 0]], 
[[1, 0, 2], [2, 0, 1], [0, 1, 2], [2, 1, 0], [0, 2, 1], [1, 2, 0]], 
[[1, 0, 2], [2, 0, 1], [2, 1, 0], [0, 1, 2], [0, 2, 1], [1, 2, 0]], 
[[1, 0, 2], [2, 1, 0], [0, 2, 1], [2, 0, 1], [0, 1, 2], [1, 2, 0]], 
[[1, 0, 2], [2, 1, 0], [2, 0, 1], [0, 2, 1], [0, 1, 2], [1, 2, 0]]
]

The other half can be obtained by subtracting each preceding row from:

2*[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

And by placing it at symmetric position, i.e. at 48-i+1 instead of i
here for 1<=i<=24 (of course); This is obtained in such way due all
those permutations of permutations were listed initially in increasing
sequence.

The Steinhaus-Jhonson-Trotter algorithm has associated a different kind of autosimilarity. The 1st differences for its output behaves in all the cases a precise algorithmic pattern in which the algorithm itself is involved, repeated, indeed alternating its parameters.

For a quick example try:

vecPolyEval(vecFirstPartialSums2(vecDiff1(permSJT(4,1,1))))

And then try the same without the outer call to vecPolyEval()

The try the same for other values n<4, and n>4 and compare the outputs.

*/

vecPolyEval(v0,B=10)=vector(#v0,i,subst(Pol(v0[i]),x,B));

/*
      "Uniformly complementary set" (definition): It is an "U. c. set" any partially ordered set "S" containing k integers such that, given an integer constant R, those elements in S placed at symmetric positions are mutually one the arithmetic complement to R of the other, this is: x[i]+x[k-i+1]=R, for every i in 1<=i<=k and x[i], x[k-i+1] in S;
      
      The routine so coded below is an exclusive application of the previous definition to permutations for the n letters 0..n-1;
*/

fixToUniformlyComplementary(v,n)={
  my(w:list,s=(n-1)*vector(n,i,1),u=vector(#v,i,vector(n)),c=1,a);
  w=List();
  if((#v==n!)&&(n>1),
    for(k=1,#v,listput(w,v[k]));
    while(#w,
      u[c]=w[1];
      u[#u-c+1]=s-u[c];
      listpop(w,1);
      for(k=1,#w,if((s-u[c])==w[k],a=k;break));
      if(a,listpop(w,a));
      a*=0;
      c++
    );
    return(u)
  )
}

isUniformlyComplementary(S,n)={
  my(v=(n-1)*vector(n,i,1));
  for(j=1,#S,
    if((S[j]+S[#S-j+1])!=v,return(0))
  );
  return(1);
}

/*
   Implementations:
   For 3 known permutation generating algorithms:
    i) Steinhaus-Johnson-Trotter (A207324),
    ii) Schmuel Zaks (A055881),
    iii) Narayana Pandit (A237265)
*/

/*The following routine implements recursively the Steinhaus-Jhonson-Trotter algorithm trough a sieve based on modular arithmetic. Usage: Initial "d"iagonal: 0 "/" (default) or 1 "\"; "w"aving diagonals? 1 "yes" (default), or 0 "no"; Output "format" 1 "A vector of vectors" (default), or 0 "A huge vector" */
permuteSJT_1(n,d=0,w=1,format=1)={
  if(n<1,return([]));
  if(n==1,return([0]));
  if(n==2,if(d,if(format,return([[1,0],[0,1]]),return([1,0,0,1])),if(format,return([[0,1],[1,0]]),return([0,1,1,0]))));
  my(u=permuteSJT_1(n-1,d,w,0)); /* Internally we use only the output format zero. */
  my(c=1,sqr_n=n*n);
  d=!d;
  my(v=vector(n!*n,i,0*if(w&&!((i-1)%sqr_n),d=!d)+(n-1)*(!d*(((i%sqr_n)%(n-1)==1)&&(1!=(i%sqr_n)))+!!d*((!(i%sqr_n))||(1==((i%sqr_n)%n-(i%sqr_n)\n))))));
  for(k=0,(n-1)!-1,
    for(j=1,n,
      for(i=1,n-1,
        if(c<=#v,
          while(v[c],c++);
          v[c]=u[k*(n-1)+i];
          c++
        )
      )
    )
  );
  c*=0;
  if(format,return(vector(n!,y,vector(n,x,v[c++]))),return(v))
} /* Note(s): 1) Here the usage of divrem() was avoided intentionally. 2) This is an experimental implementation: Probably slower than other choices. */

aux01(a,b)=if(b,b,a);

aux02(m,z,y,x)=if(z,(x==y),(m+1==x+y));

permuteSJT_2(n,turnUniformlyComplementary)={ /* Adaptation from an old implementation found in links at A207324 */
  my(z,q,v0,v=vector(n!,j,vector(n)),t=1,x=1,y=1,m=0);
  if(n>1,
    v0=permuteSJT_2(n-1);
    m=n-1;
    q=0;
    z=0;
    for(i=1,n!,
      for(j=1,n,
        v[i][j]=m*aux02(n,z,aux01(n,i%n),j);
        if(!v[i][j],
          v[i][j]=v0[y][x];
          if(x==m,x=1;if(t==n,t=1;y++,t++),x++);
        );
        q++;
      );
      if(q==n^2,q=0;z=!z);
    );
  if(!turnUniformlyComplementary,v,fixToUniformlyComplementary(v,n)),
  return([[0]])
  )
} /* Please notice extra routines aux01() and aux02() are required by this implementation. */

permuteZaks(n,symmetryHack=1)={
  my(rfc=vector(n),
     j,
     a,
     p=vector(n,k,k-1),
     k,
     t,
     S,
     P=vector(n!),
     b=n!/(1+(n>1)*(!!symmetryHack)),
     Z=(n-1)*vector(n,i,1)
  );
  while (1,
    P[S++]=p;
    if(symmetryHack&&n>1,P[#P-S+1]=Z-p);
    j=1;
    while(rfc[j]==j,
      rfc[j]=0;
      j+=1;
    );
    if(S==b,
      return(P)
    );
    rfc[j]+=1; 
    a=j;
    j+=1;
    k=1;
    while(k<j,
      t=p[j];
      p[j]=p[k];
      p[k]=t;
      k+=1;
      j-=1;
    );
  );
}

nextpermute(v)={
  my(q,l,k,t);
  forstep(c=#v-1,1,-1,
    if(v[c]<v[c+1],
      k=c;
      break)
  );
  if(k,
    forstep(c=#v,k+1,-1,
      if(v[k]<v[c],
        l=c;
        break
      )
    );
    t=v[k];
    v[k]=v[l];
    v[l]=t;
    q=vector(#v-k,j,v[k+j]);
    for(j=1,#q,
      v[k+j]=q[#q-j+1]
    );
    v
  ,
    []
  )
} /* Inspired by the routine of the same name available in C++ */

permutePandit(n,turnSymmetric)={
  if(n==1,return([0]));
  my(t=(n-1)*vector(n,i,1));
  my(a=vector(n,i,i-1));
  my(b=vector(n!));
  b[1]=a;
  b[#b]=t-a;
  for(i=1,n!/2-1,
    b[i+1]=nextpermute(b[i]);
    b[#b-i]=t-b[i+1];
  );
  if(!turnSymmetric,b,fixToUniformlyComplementary(b,n));
} /* Last "if()" is actually unnecessary, 
     due output is always already fixed
     in such way. It is kept here "as is"
     just for illustrative purposes. */


/* MISCELLANEUS ROUTINES ON PERMUTATIONS -- Section start */

/* Based on the definition for A055881, and the corresponding PARI/GP program by Charles Greathouse IV */
permuteZaks2(n)={
  my(Q=n!,v=vector(n,j,j-1),t,k,m,w=vector(n!),u=(n-1)*vector(n,j,1));
  w[1]=v;
  w[#w]=u-v;  
  for(c=1,Q/2-1,
    m=c;
    k=2;
    while(!(m%k),m/=k;k++);
    for(i=1,k/2,
      t=v[i];
      v[i]=v[k-i+1];
      v[k-i+1]=t;
    );
    w[c+1]=v;
    w[Q-c]=u-v;
  );
  w
} /* This one already takes into account the symmetry. */

nextZaks(inputVec,k)={ /* Next Zaks's algorithm redundant permutation for inputVec with index k modulo factorial(#inputVec) */
  my(c=2,z,outputVec=inputVec);
  k%=(#outputVec)!;
  if(k,
    while(!(k%c),c++);
    for(i=1,c\2,
      z=outputVec[i];
      outputVec[i]=outputVec[1+c-i];
      outputVec[1+c-i]=z;
    )
  );
 return(outputVec);
}

permuteZaksRedundant(n,v0)={ /* EXPERIMENTAL, intended to study structural and combinatorics properties of Zaks's algorithm */
  my(S=vector(max(n,#v0)!));
  S[1]=v0;
  for(j=1,#S-1,
    S[j+1]=nextZaks(S[j],j);
  );
  return(S);
}

demoComparisonsZaksRedundant(A,B)={
   my(a=min(A,B),b=max(A,B),u);
   my(v=vector(a,i,i-1),L=permuteZaks2(a));
   my(w=vecsort(permuteZaksRedundant(b,v),,8));
   for(k=1,#L,
     u=permuteZaksRedundant(b,L[k]);
     print1([#u/#w,contained(L,u)]" ");
   );
   print("\n");
} /* WARNING: Apparently this crashes the GP Calculator easily (by segmentation faults).
              Use with care (works with small values ). */
              
/* MISCELLANEOUS ROUTINES ON PERMUTATIONS -- Section end */

/* ========================
            On the
          Structural
    conjectures at A217626
    
           (part i)
   ======================== */

/*

Recent experiments reveal that analogous conjectures for other algorithms (at least for the Zaks's one) must hold also (without known exceptions), suggesting the fact that: Beyond the symmetry, also some kind of autosimilarity will be granted inside the corresponding analogue of A217626 if the permutation algorithm used there satisfies the (necessary but NOT enough) condition "Q=P"; (i.e. if such algorithm always generates an uniformly complementary output).

In the case of Zaks's algorithm, the numeric values obtained are scaled by a common constant factor. For illustrating this feature, notice that the analogue of conjecture #1 at A217626 for Zaks's algorithm would state the same counter of (M-n+1)! repetitions, however by taking into account the missing factor, it is found such factor must be 10^(M-n) meaning it that the first m!-1 terms are inserted with a symmetric pattern of distribution, repeated inside the first M!-1 terms, BUT ALSO multiplied all of them by 10^(M-n);

Such "scaling factor" is NOT present in A217626, therefore (barely, for now!) conjecture #2 at A217626 holds; The simple autosimilarity pattern identified there at A217626, apparently is associated only to the Narayana Pandit's algorithm.

*/

precompPermutationsZaksExperiment(K)={
  
   my(p,j);
  /* my(p,q,r,j); */
  
  while((j+1)!<K+1,j++); /* With vectors: Kth differences requires K+1 elements */
    
  p=vector(9-j,i,permuteZaks(i+j,1)); /* Generating n! permutations for the n (in 2..9) letters: 0..n-1 */
                                      /* By using the Schmuel Zaks's algorithm related to A055881 */
  /*     
  q=vector(#p,i,vector(#p[i],j,p[i][j]-p[i][#p[i]-j+1])); \\ Anti-symmetric redefinition, step 1/2 
  r=vector(#q,i,vector(#q[i],j,(q[i][j]+q[i][#q[i]])/2)); \\ Anti-symmetric redefinition, step 2/2 
                                                          \\ Please refer by analogy to corresponding comment at A215940  
  return(r);                                              \\ Or alternatively see the final transcriptions.
  */
  return(p);
  
}

prepareExperiment(r,K=1)={ /* K differences "order" */
  
  my(s,t,u);
  
  s=vector(#r,i,vecDiff(r[i],K)); /* Computing the Kth differences for each case of n */
  
  t=vector(#s,i,vecFirstPartialSums2(s[i])); /* Performing the transformation isomorphic to dividing by B-1 */
  
  u=vector(#t,i,vecPolyEval(t[i])); /* Interpreting the vector elements as coefficients for a power series in B */
                                    /* and evaluating those series vector by vector */
  
  return(u)
    
}

performExperimentCheck01(r,U=1,B=10)={ /* U highest K to test, B base or radix, B=10 for decimal, B=16 for Hexadecimal, and so on. */

  my(Q,c=1);
  
  for(K=1,U,
    Q=prepareExperiment(r,K);
    forvec(y=vector(2,i,[1,#Q]),
      c*=(contained(Q[y[1]]*10^(y[2]-y[1]),Q[y[2]])==(y[2]-y[1]+1)!);
      if(!c,return(0));
    ,2)    
  );
    
  return(1)
}

/* EXAMPLE
 
 Try this:

 ----------------[start]
 
 U=1; \\ Up to 1st differences.
 r=precompPermutationsZaksExperiment(U);
 print( prod(B=2,10,performExperimentCheck01(r,U,B)) );
 
 ----------------[end]
 
 Which should print "1" and could take around 3 minutes (tested without a GP2C compilation).

 Also try:
 
 ----------------[start]
 
 U=10; \\ Up to tenth differences.
 r=precompPermutationsZaksExperiment(U);
 print( performExperimentCheck01(r,U,2) );
 
 ----------------[end] 

 Which should print "1" and could take around 4 minutes (tested without a GP2C compilation).

 Notice here (and get yourself convinced of the fact) that these results are BASE INDEPENDENT;

*/

prepareExperiment_Bi(r,K=1)={ /* K differences "order" */
  
  my(s,t,u);
  
  s=vector(#r,i,vecDiff(r[i],K)); /* Computing the Kth differences for each case of n */

  t=vector(#s,i,vecRemoveZeroEdges2(s[i])); /* Removing mainly those trailing zeros that make the scaling for terms among different terms */
  
  u=vector(#t,i,vecFirstPartialSums2(t[i])); /* Performing the transformation isomorphic to dividing by B-1 */
    
  return(u)
    
}

performExperimentCheck01_Bi(r,U=1)={ /* U highest K to test, B base or radix, B=10 for decimal, B=16 for Hexadecimal, and so on. */

  my(Q,c=1);
  
  for(K=1,U,
    Q=prepareExperiment_Bi(r,K);
    forvec(y=vector(2,i,[1,#Q]),
      c*=(contained(Q[y[1]],Q[y[2]])==(y[2]-y[1]+1)!);
      if(!c,return(0));
    ,2)    
  );
    
  return(1)
}

/*
 
 The point is, now you can obtain here the same common counters that was obtained for any base with the other routines. 

 EXAMPLE

----------------[start]

\\ *Please: Always remember to allocate enough memory before proceeding!
\\         (The present example was run with a parisize=3072000000 setup, just in case)
U=10;
r=precompPermutationsZaksExperiment(U);
\\ time = 1,857 ms.
performExperimentCheck01_Bi(r,U)
\\ time = 1min, 37,523 ms.
\\ %3 = 1

----------------[start]

Now due these other kind of experiments are BASE INDEPENDENT, the time consumption due polynomial evaluation is saved,
however the memory management for your O.S. behind your GP Calculator, might make it actually slow.
 
*/

/* ========================
            On the
          Structural
    conjectures at A217626
    
           (part ii)
   ======================== */

/* The following routine is intended to prove that the Zaks's algorithm (commented at A055881) for generating permutations would be the second known case for a permutation generating algorithm that satisfy the condition "Q=P" described in conjecture #2 of A217626, this is: Such algorithm also generates an already "Uniformly complementary" output just like the Narayana Pandit's algorithm (for permutations listed in increasing sequences) does, therefore symmetry and autosimilarity properties would be expected to be found in analogy to A217626 after applying analogous definitions and by performing analogous calculations with the exception of replacing the permutations generating algorithm.

conjecture1_Zaks(n,M)={my(lambda=vecRemoveZeroEdges2(vecDiff1(permuteZaks(min(n,9),1))));vector(min(M,9),i,contained(lambda,vecRemoveZeroEdges2(vecDiff1(permuteZaks(i,1)))))}

EXAMPLES

Example #1 (please copy/paste and execute with GP):

\\ *Begin*

stub=vector(9,k,vecFirstPartialSums2(vecDiff1(permuteZaks(k,1)))); \\  First k!-1 terms for Zaks's analogue of A217626;
tbl=matrix(#stub,#stub,i,j,contained(vecRemoveZeroEdges2(stub[i]),vecRemoveZeroEdges2(stub[j])));
print(tbl);

\\ *End*

Such table must be exactly this one:

[1, 2, 6, 24, 120, 720, 5040, 40320, 362880;
 0, 1, 2,  6,  24, 120,  720,  5040,  40320;
 0, 0, 1,  2,   6,  24,  120,   720,   5040;
 0, 0, 0,  1,   2,   6,   24,   120,    720;
 0, 0, 0,  0,   1,   2,    6,    24,    120;
 0, 0, 0,  0,   0,   1,    2,     6,     24;
 0, 0, 0,  0,   0,   0,    1,     2,      6;
 0, 0, 0,  0,   0,   0,    0,     1,      2;
 0, 0, 0,  0,   0,   0,    0,     0,      1]

Indeed identical to:

chk=matrix(#stub,#stub,i,j,(j>=i)*abs(j-i+1)!);

As expected according to conjecture #1 at A217626
and its analogue here with an identical statement;

However, these facts are NOT rabbits emerging from a hat...

The missing scaling factor at A217626 here is evidently present:

Example #2 (please copy/paste and execute with GP):

\\ *Begin*

stub=vector(7,k,vecFirstPartialSums2(vecDiff1(permuteZaks(2+k,1)))); \\  First (k+2)!-1 terms for Zaks's analogue of A217626; (1<=k<=7)
sample=vector(#stub,i,stub[i][#stub[i]]);
print(sample~);

\\ *End* 

Therefore: Here conjecture #1 would require additional statement describing the scaling factor 10^(M-n);

The output for this 2nd example was intended to appreciate it:

 [
                     [1, 0],
                  [1, 0, 0],
               [1, 0, 0, 0],
            [1, 0, 0, 0, 0],
         [1, 0, 0, 0, 0, 0],
      [1, 0, 0, 0, 0, 0, 0],
   [1, 0, 0, 0, 0, 0, 0, 0]
 ];

*/

/* Observations:

   The Zaks permutation generating algorithm satisfies the condition Q=P from conjecture 2, however the autosimilarity cannot be appreciated directly. This time for Zaks's ordering, if 1<=n<=M are two positive integers, then those elements in sequence "as is" for the first m!-1 terms, are inserted with symmetric distribution inside the sequence "as is" for the first M!-1 elements, repeated (M-n+1)! times, but with each corresponding term differing among both sequences by a factor of 10^(M-n);
   
   This is, the autosimilarity occurs, but now scaling must be took into account.
   
   The remarkable fact here is: Both algorithms the Narayana Pandit for lexical increasing sequences and the Schmuel Zaks algorithm generate their own "already uniformly complementary" outputs.
   
   Moreover, there is an unexpected fact that can be interpreted by adding instead of subtracting the output for both algorithms:
   
   (n+1)!=A000142(n+1) counts among the number of distinct possible ways for decomposing n*(n+1) as the sum of (n+1) nonnegative integers each one less or equal than 2*n; These that are distributed with a symmetric pattern inserted inside an exhaustive list in increasing order containing all the possibilities.
   
   Indeed the careful concatenation of summands in these (n+1)! possibilities described previously, is a palindrome if we read it as the digits for a number.
  
  And the count for total number of possibilities in a full list should match "Q" for the following result:

  */

counterExp02(k)={
  my(Q,n=min(k,9));
  my(L:list);
  L=List();
  forvec(y=vector(n,j,[0,2*(n-1)]),
    if(vecsum(y)==2*binomial(n,2),
      listput(L,y);
      Q++
    ),0
  );
  vector(#L,i,L[i]);
}

/* To determine if elements in "these" are present among the elements for "here"
   also verifying its distribution pattern... */

areTheyPresent(these,here)={
  my(v=vector(#here));
  if(#these>0,
    my(x,L:list);
    L=List(vecsort(these,,8));
    while(#L,
      x=L[1];
      listpop(L,1);
      for(i=1,#v,
        if(x==here[i],v[i]++)
      )
    )
  );
  v
}


vecIsSymmetricByReverses(v)={
  for(i=1,#v\2,
    if(vector(#v[i],k,v[i][#v[i]-k+1])!=v[#v-i+1],return(0))
  );
  return(1);
}

vecPatternOfSymmetryByReverses(v,strict=0)={
  my(w=vector(#v));
  for(i=1,#v\2,
    if(vector(#v[i],k,v[i][#v[i]-k+1])==v[#v-i+1],w[i]++;w[#v-i+1]++)
  );
  w
}

/* Now it is possible to evidence that the preceding statements about distribution
 * are true: By running the following example,
 

  --------------[Example start]--------------
  
  t=7;
  A=vector(t,j,permutePandit(j,0)+permuteZaks(j,1));
  b=vector(#A,i,isSymmetric(areTheyPresent(A[i],counterExp02(i,A))));
  print(b);
  
  --------------[Example end]--------------
    
  It must print a repunit vector: [1,1,...,1]
 
  UNFORTUNATELY due NOT to design/conceptual reasons but technical limitations
  instead, such analysis might be currently unavailable for t>7, at least in
  the simple form shown above by the example.
  
  At purpose of the corresponding counters:
  
    vector(7,i,#counterExp02(i,A))
  
  which takes around 2min, 10secs
  
  returns: [1, 3, 19, 231, 3951, 88913, 2473325]

  Here the first differences for elements in "A" are symmetric.
  
  The first 3 elements in "A" are symmetric by reverses, this is,
  the concatenation of its values are palindromes.
  
  For every element in "A", it is also symmetric the result
  of vecPatternOfSymmetryByReverses() operating on them;
  
  As an example of the statement for the symmetric distribution pattern:
  
  c=vector(7,i,isSymmetric(areTheyPresent(A[i],counterExp02(i))));
  
  with time = 29min, 14,707 ms.

  As expected it replies [1, 1, 1, 1, 1, 1, 1];
  
 */



/* The following definition/routine is intended to satisfy for n>2 that the following expression:
 
        vecVecsum(vecFirstPartialSums2(permutePandit(n)-permuteZaks(n)))==-1*ExperimentalSeq01(n)

returns true ("1") when it is evaluated.

The meaning of such definition/routine is as follows. In order to sequence A217626...

You pick two different consecutive permutations for the n letters 0..n-1 from a same set among of the (n!)! of
possible arrangements or enumerations you might list those n! permutations.

----------- BUT NOW,

Notice you did that always using the output of the same algorithm (up to (n!)! of them are possible, yes!,
but to the own taste on logic for the author of this file, those relevant algorithms in the sense of enabling autosimilarity
should be only 2, because 2!=2 and indeed (...(((2!)!)!)!.....)!==2 is true).

What is proposed now is to choose a pair of algorithms, for example like it was done here below, the Narayana Pandit, and the
Schmuel Zaks algorithms, and then instead of subtracting consecutive permutations, now we subtract the ith permutation
(Either 1<=i<=n! or 0<=i<=n!-1 depending on the readers choice) between these algorithms.

Precisely as it was described... such procedure is implemented here by ExperimentalSeq01(n) which returns the n! differences
between the output for both algorithms, "divided by 9" ( Actually what is done instead of a division is the "trick" performed by
vecFirstPartialSums2( ), the reason for which more general base independent results are granted )

Something curious happen there, it is not the vector of "digits" what has the autosimilarity. This time we pick each one and take
summation over all its components using the result as replacement... 

*/

ExperimentalSeq01(n)={
  if(n==1,return([]));
  my(rfc=vector(n),
     j,
     a,
     p=vector(n,k,k-1),
     k,
     t,
     S,
     P=vector(n!),
     b=n!/2
  );
  my(w=p,u=vector(n-1));
  while (1,
    P[S++]=p-w;
    u*=0;
    for(i=1,#u,u[i]=sum(j=1,i,P[S][j]));
    P[S]=vecsum(u);
    P[#P-S+1]=-P[S];  
    w=nextpermute(w);  
    j=1;
    while(rfc[j]==j,
      rfc[j]=0;
      j+=1;
    );
    if(S==b,
      return(P)
    );
    rfc[j]+=1; 
    a=j;
    j+=1;
    k=1;
    while(k<j,
      t=p[j];
      p[j]=p[k];
      p[k]=t;
      k+=1;
      j-=1;
    );
  );
}

/* Some observations/comments:
 
 For n>2, ExperimentalSeq01() evidences a similar kind of autosimilarity in comparison with A217626,
 however this time they are NOT factorials those counters for the number of times a sequence appears
 inserted repeatedly inside another larger sequence (conjecture #1 @ A217626). */
 
/* Execution sample for ExperimentalSeq01() studying its properties.
 
-------------------------------------- [Sample starts]
 
 ? Q=vector(8,i,ExperimentalSeq01(2+i));
time = 25,077 ms.

 ? C=matrix(#Q,#Q,i,j,contained(Q[i],Q[j]));
time = 1min, 27,582 ms.
 
 ? print(ceil(C/2));

[1 1 2 4 8 17 38 92]
[0 1 1 2 4  8 16 33]
[0 0 1 1 2  4  8 16]
[0 0 0 1 1  2  4  8]
[0 0 0 0 1  1  2  4]
[0 0 0 0 0  1  1  2]
[0 0 0 0 0  0  1  1]
[0 0 0 0 0  0  0  1]

-------------------------------------- [Sample ends]
 
 At least the first row preceded by an "1" match first terms in A118928; */
 
 A118928(n)=if(!n,!n,sum(k=!1,n\2,binomial(n-k,k)*binomial(n-k,k+1)/(n-k)*A118928(k)));
 
/* 
 
 The next rows "weakly" evidence that these counters might be all of them
 belonging the same sequence (... should it be 2*A118928(M-n+1) for M>n?).
 
 Curiously and perhaps remarkable is it the fact that, at the present instant
 when this file is just wrote, A118928 is apparently the unique sequence
 already present at OEIS.org that seems to match with these counters;
 
*/

/*
   Note: If some parts of the code
         were commented here, it is
         due there at author's machine
         such code is already loaded
         after the /etc/gprc start up
         settings are applied.

         
 Appendix:  Transcription for the base independent treatment explained with comments at A215940 and illustrative program;
=========== 

Contribution by R. J. Cano, Apr 29 2016, (Start)

Although in the sequence name it reads: "permutation of (1,...,m)", the most general statement that could replace it is: "permutation of any m-tuple of integers all of them in arithmetic progression", obtaining a multiple of this sequence, lambda*a(n), where lambda is the common difference for the progression. It works in such way because only the differences is what matters here.

Given x>1 and k>=0, if a polynomial G(x) of degree k is divided by x-1 then the remainder will be the sum of all the coefficients in G; Let us consider the case in which those coefficients are the differences among the letters ("digits") of two permutations for the same set of letters (0..x-1): The sum of all those differences must vanish. This explains why the difference between two of such permutations expressed in base x is 0 mod x-1, particularly why differences for pairs of permutations are divisible by 9.

Another way of introducing this sequence takes advantage of the fact that for n>1, n! is even. Consider for n>1 to obtain only the first n! terms; This can be done by subtracting the last permutation from the first, the penultimate permutation from the second, and so on by following the pattern (P(k)-P(n!-k+1))/9 with 1<=k<=n!; such procedure generates an antisymmetric sequence f(k) from which a(k)=(f(k)+f(n!))/2; This partially explains why A217626 is symmetric. Also a base-independent treatment is possible using linear algebra: Column vectors and the strictly lower triangular matrix instead of the division by (r-1) where r is the base (and r=10 here for this sequence). This approach leads one to conclude that terms in this sequence are the differences between pairs of vectors made from the first n-1 partial sums of letters ("digits") taken from permutations for n consecutive letters, when components in these vectors are viewed as coefficients for a power series in r=10.

(End) 


Illustrative program: For the comment part about arithmetic progressions (routine name is modified here obviously due the present context).
============ ======== 

*/

A215940firstTerms(m, lambda, base=10)={ /* First m! terms. */
  my(v0=vector(m,j,(j-1)*lambda));
  my(Q=(#v0)!);
  my(v=vector(Q,i,numtoperm(#v0,i-1)));
  forvec(y=[[1,Q],[1,#v0]],v[y[1]][y[2]]=v0[v[y[1]][y[2]]]);
  for(i=2,#v,v[i]-=v[1]);
  v[1]*=0;
  my(w=vector(#v,i,subst(Pol(v[i]),x,base)/(lambda*(base-1))));
  return(w);
}

/*
 
 Appendix:  Transcription for the statements of the 3 conjectures commented at A217626;
=========== 

Contribution by R. J. Cano, Apr 04 2016 (Start)

Conjecture 1: Given 1<n<=M two positive integers, the first n!-1 terms of this sequence are inserted (M-n+1)! times with (anti)symmetric distribution among the first M!-1 terms of this sequence. The described count and alternating pattern of symmetry is conserved whenever it is possible (i.e. when having enough terms) through successive differences and for the corresponding sequences (i.e. the first differences of A217626 and so on).

Lemma: Let be P an arbitrary set consisting of m integers; Let be x[i] an element in P (with 1<=i<=m); Let be y[j]=x[j+1]-x[j] (with 1<=j<=m-1) the 1st differences of P. These differences are symmetric if y[j]=y[m-j] which for P implies the condition x[j]+x[m-j+1]=x[j+1]+x[m-j];

Consequence: When m=n! and P is a set with all the permutations for the letters 0..n-1, the preceding lemma implies P has associated at least a set Q such that 1st differences in Q are symmetric.

Generating algorithm: Such Q can be built based upon P and the condition given by the preceding lemma if it is removed from P (until P becomes empty) its 1st element tau, inserting them both in Q tau and its arithmetic complement to repdigit (n-1)*111...1 (n times 1) removing the mentioned complement from P.

Conjecture 2: The autosimilarity shown by a(n) is a consequence of the fact that the corresponding P is the set of the n! permutations in increasing sequence for the letters 0..n-1, and Q=P (it holds if they are replaced "a(n)" and "increasing" respectively with "-1*a(n)" and "decreasing").

Note: "Q=P" is a necessary but not enough condition for observing the autosimilarity in a(n).

Application: The "generating algorithm" described previously might be potentially useful for parallel computing. In combination with the partition scheme proposed at links in A237265, and multiple indirection. For example notice that in such sense an algorithm for generating k! permutations with an increasing sequence would require only k!/2 iterations because the other half would be already determined by symmetry.

Conjecture 3: For n>2, given P the set of permutations in increasing sequence for the letters 0..n-1, there are distributed with a symmetric pattern among its (n!)! permutations those A000165(n!\2) such that their 1st differences are symmetric. Moreover by setting to zero the other elements whose 1st differences are not symmetric, we obtain an antisymmetric sequence.

(End) 


 Used host(s) features:
 
   OS: "Supernova" GNU Slackware64 Linux 14.2 rc1
   GP/PARI CALCULATOR Version 2.7.5 (released)
   x86-64/GMP-6.1.0 kernel 64-bit version
   Linux Kernel 4.4.3 running on x86_64 AMD E-300 APU with Radeon(tm)
   4GB RAM installed.
   Source successfully compiled with GP2C and installed to /etc/gp;

   Also (finished there on 2016 Apr 29):
   OS: "Endurance" GNU Slackware Linux 14.1 (32Bits)
   GP/PARI CALCULATOR Version 2.7.5 (released)
   ix86/GMP-5.1.3 kernel 32-bit version
   Linux  Kernel 3.10.17-smp running on i686 Genuine Intel(R) CPU N270 @ 1.60GHz
   1GB RAM installed.
   Source successfully compiled with GP2C and installed to /etc/gp;
   
 Special Acknowledgments:
   
    To Lucy Ramirez for gently allowing me to use her "Satellite C855D" on Tue, 2016 Apr 12.

    To Deiby Parra Marquez for gently allowing me to use her AOC 17" monitor on Fri, 2016 Apr 29.

    To Alfred "Panda bear" Osuna for gently allowing me to use one of his monitors during second half of May 2016.

    To OEIS.org my beloved family (JsJ).
    
Sourcecode file ends here. */